package com.jzo2o.orders.manager.job;

import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.enums.OrderStatusEnum;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.manager.service.IOrdersCreateService;
import com.jzo2o.orders.manager.service.IOrdersRefundService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 订单取消业务定时任务
 *
 * @Author mr.lin
 * @Date 2025/2/7 16:09
 */
@Slf4j
@Component
public class OrderJob {

    @Autowired
    private IOrdersRefundService ordersRefundService;

    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 批量操作取消订单业务
     */
    @XxlJob("handleRefundOrders")
    public void bathOrderRefund() {

        //1.为了控制获取订单退款表的数量,采取每次获取100条数据,操作完将其删除
        List<OrdersRefund> ordersRefundList = ordersRefundService.lambdaQuery()
                .last("limit 100")
                .list();
        if (CollUtils.isEmpty(ordersRefundList)) {
            return;
        }
        OrderJob owner = applicationContext.getBean(OrderJob.class);

        //2.遍历集合,一个个处理退款操作
        for (OrdersRefund ordersRefund : ordersRefundList) {

            owner.ordersRefundHandle(ordersRefund);

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void ordersRefundHandle(OrdersRefund ordersRefund) {
        //1. 先看看有没有这个订单
        Orders orders = ordersCreateService.getById(ordersRefund.getId());
        if (orders == null) {
            return;
        }
        //2. 当退款状态是成功退款或失败退款时 就不用进行退款操作了
        if (Arrays.asList(OrderRefundStatusEnum.REFUND_SUCCESS.getStatus(), OrderRefundStatusEnum.REFUND_FAIL.getStatus()).contains(orders.getRefundStatus())) {
            return;
        }
        //3.判断订单状态是不是已关闭 (在退款业务的时候,用户发起退款通知,先把订单状态改为了订单已关闭)
        if (ObjectUtils.notEqual(orders.getOrdersStatus(), OrderStatusEnum.CLOSED.getStatus())) {
            return;
        }
        //4.通过Feign接口调用微信退款接口
        ExecutionResultResDTO executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
        if (executionResultResDTO == null) {
            log.error("[订单退款处理]退款申请接口调用失败，退款信息：{}，异常信息", ordersRefund);
            throw new BadRequestException("[订单退款处理]退款申请接口调用失败");
        }
        if (ObjectUtils.equals(executionResultResDTO.getRefundStatus(), OrderRefundStatusEnum.REFUNDING.getStatus())) {
            // 还是退款中的情况
            //5.如果第一次调用Feign接口 还是退款中的话 就让线程睡三秒 再次进行调用
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
        }
        //5.更新订单表字段(refund_status refund_no refund_id)
        boolean flag = ordersCreateService.lambdaUpdate()
                .set(Orders::getRefundStatus, executionResultResDTO.getRefundStatus())
                .set(Orders::getRefundNo, executionResultResDTO.getRefundNo())
                .set(Orders::getRefundId, executionResultResDTO.getRefundId())
                .eq(Orders::getId, orders.getId())
                .update();
        if (!flag) {
            log.error("[订单退款处理]订单表退款状态更新失败，退款信息：{}", ordersRefund);
            return;
        }
        //6. 将订单退款表中的数据删除
        boolean flag1 = ordersRefundService.removeById(ordersRefund.getId());
        if (!flag1) {
            log.error("[订单退款处理]删除退款记录失败，退款信息：{}", ordersRefund);
            return;
        }
        log.info("[订单退款处理]退款处理成功，退款信息：{}，退款状态：{}", ordersRefund, executionResultResDTO.getRefundStatus());
    }


    @Autowired
    private RefundRecordApi refundRecordApi;


    @Autowired
    private IOrdersCreateService ordersCreateService;
}
